/*
 *                    COPYRIGHT NOTICE
 *
 *           This code is copyright protected by Freedom Inc.
 *
 *              2001-2012 All Rights Are Reserved
 */
package com.freedom.oldsong.util;

import java.math.BigDecimal;

import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

/**
 * This class is an utility class, providing some common method for formarting
 * or converting.

 * @author steven.wang
 *
 */
public final class FormatUtils {
	
	
	/**
	 * Creates a new instance of FormatUtils.
	 *
	 */
	private FormatUtils(){
		
	}
	
	/**
	 * @name logger
	 * @type Logger
	 */
	private static final Logger logger=Logger.getLogger(FormatUtils.class);
	
	/**
	 * @name BLEUM_DATE_FORMAT
	 * @type String
	 */
	private static final String BLEUM_DATE_FORMAT = "MM/dd/yyyy";

	/**
	 * @name BLEUM_DATE_TIME_FORMAT
	 * @type String
	 */
	private static final String BLEUM_DATE_TIME_FORMAT = "MM/dd/yyyy hh:mm";

	/**
	 * @name BLEUM_DATE_TIME_FORMAT_24H
	 * @type String
	 */
	private static final String BLEUM_DATE_TIME_FORMAT_24H = "MM/dd/yyyy HH:mm";

	/**
	 * @name BLEUM_DATE_FORMAT_REST
	 * @type String
	 */
	private static final String BLEUM_DATE_FORMAT_REST = "yyyyMMdd";

	/**
	 * date formater.
	 * 
	 * @param date
	 *            the date.
	 * @param pattern
	 *            the format pattern.
	 * @return date string formatted.
	 */
	/**
	 * @name formatDate
	 *
	 * @param date
	 * @param pattern
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String formatDate(final Date date, final String pattern) {

		String fmt = pattern;

		if (date == null) {
			return "";
		}
		if (pattern == null) {
			fmt = BLEUM_DATE_FORMAT;
		}

		DateFormat fmter = new SimpleDateFormat(fmt);
		return fmter.format(date);

	}

	/**
	 * Validate and parse date
	 * 
	 * @param date
	 * @return null if the input date is wrong date if the input date is right
	 */
	/**
	 * @name validateParseDate
	 *
	 * @param date
	 * @return    
	 * Date     
	 * @throws 
	*/
	public static Date validateParseDate(String date) {
		if (date == null || "".equals(date.trim())) {
			return null;
		}
		return parseDate(date);
	}

	/**
	 * Convert string to int
	 * 
	 * @param str
	 * @return int value
	 */
	/**
	 * @name toInt
	 *
	 * @param str
	 * @return    
	 * int     
	 * @throws 
	*/
	public static int toInt(String str) {
		if (str != null && !"".equals(str.trim())) {
			try {
				return Integer.parseInt(str.trim());
			} catch (Exception e) {
				return 0;
			}
		}
		return 0;
	}

	/**
	 * Convert string to long
	 * 
	 * @param str
	 * @return long value
	 */
	/**
	 * @name toLong
	 *
	 * @param str
	 * @return    
	 * Long     
	 * @throws 
	*/
	public static Long toLong(String str) {
		if (str != null && !"".equals(str.trim())) {
			try {
				return Long.valueOf(str.trim());
			} catch (Exception e) {
				return null;
			}
		}
		return null;
	}

	/**
	 * @name formatLoginName
	 *
	 * @param name
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String formatLoginName(String name) {
		if (name == null || name.trim().length() <= 1) {
			return name;
		}
		String temp = name.trim().replaceAll(" ", ".");
		int index = temp.indexOf('.');

		if (index < 0) {
			temp = temp.substring(0, 1) + temp.substring(1).replaceAll("([A-Z])(.*)", ".$1$2");
			index = temp.indexOf('.');
		}

		if (index <= 0 || temp.substring(index + 1).length() == 0 || temp.substring(index + 1).indexOf('.') >= 0) {
			return name;
		}

		StringBuilder sb = new StringBuilder();
		sb.append(name.substring(0, 1).toUpperCase());
		sb.append(temp.substring(1, index).toLowerCase());
		sb.append(temp.substring(index, index + 2).toUpperCase());
		sb.append(temp.substring(index + 2).toLowerCase());

		return sb.toString();
	}

	/**
	 * Format member name using the given splitting char
	 * 
	 * @param name
	 * @param split
	 * @return a formated name
	 */
	/**
	 * @name formatMemberNames
	 *
	 * @param name
	 * @param split
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String formatMemberNames(String name, String split) {
		if (split != null && name != null && !"".equals(name.trim())) {
			StringBuilder sb = new StringBuilder();
			if (".".equals(split)) {
				return splitName(name, split, sb);
			} else {
				String[] names = name.split(" ");
				if (names != null && names.length > 0) {
					for (String str : names) {
						sb.append(str.substring(0, 1).toUpperCase());
						if (str.length() > 1) {
							sb.append(str.substring(1));
						}
						sb.append(" ");
					}
					return sb.toString();
				}
			}
		}
		return name;
	}

	/**
	 * @param name
	 * @param split
	 * @param sb
	 * @return
	 */
	/**
	 * @name splitName
	 *
	 * @param name
	 * @param split
	 * @param sb
	 * @return    
	 * String     
	 * @throws 
	*/
	private static String splitName(String name, String split, StringBuilder sb) {
		int index = name.indexOf(split);
		if (index > 0) {
			String firstName = name.substring(0, index);
			sb.append(firstName.substring(0, 1).toUpperCase());
			if (firstName.length() > 1) {
				sb.append(firstName.substring(1));
			}
			if (index + 1 < name.length()) {
				sb.append(" ");
				String lastName = name.substring(index + 1);
				sb.append(lastName.substring(0, 1).toUpperCase());
				if (lastName.length() > 1) {
					sb.append(lastName.substring(1));
				}
			}
		} else {
			sb.append(name.substring(0, 1).toUpperCase());
			if (name.length() > 1) {
				sb.append(name.substring(1));
			}
		}
		return sb.toString();
	}

	/**
	 * date formater.
	 * 
	 * @param date
	 *            the date.
	 * @return date string formatted.
	 */
	/**
	 * @name formatDate
	 *
	 * @param date
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String formatDate(final Date date) {
		return formatDate(date, BLEUM_DATE_FORMAT);
	}

	/**
	 * @name formatDateTime
	 *
	 * @param date
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String formatDateTime(final Date date) {
		return formatDate(date, BLEUM_DATE_TIME_FORMAT);
	}

	/**
	 * @name format24HDateTime
	 *
	 * @param date
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String format24HDateTime(final Date date) {
		return formatDate(date, BLEUM_DATE_TIME_FORMAT_24H);
	}

	/**
	 * @name parseDate
	 *
	 * @param date
	 * @return    
	 * Date     
	 * @throws 
	*/
	public static Date parseDate(String date) {
		SimpleDateFormat sd = new SimpleDateFormat(BLEUM_DATE_FORMAT);
		try {
			return sd.parse(date);
		} catch (Exception e) {
			logger.error(e.getMessage());
			return null;
		}
	}

	/**
	 * @name resetDate
	 *
	 * @param date
	 * @return    
	 * Date     
	 * @throws 
	*/
	public static Date resetDate(final Date date) {
		return parseDate(formatDate(date));
	}

	/**
	 * @name parseRestDate
	 *
	 * @param date
	 * @return    
	 * Date     
	 * @throws 
	*/
	public static Date parseRestDate(String date) {
		SimpleDateFormat sd = new SimpleDateFormat(BLEUM_DATE_FORMAT_REST);
		Date restDate = null;
		try {
			restDate = sd.parse(date);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		if (formatDate(restDate, BLEUM_DATE_FORMAT_REST).equals(date)) {
			if (restDate.before(parseDate("01/01/1900")) || restDate.after(parseDate("01/01/9999"))) {
				throw new IllegalArgumentException();
			}
			return restDate;
		} else {
			throw new IllegalArgumentException();
		}
	}

	/**
	 * @name round
	 *
	 * @param scale
	 * @param number
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String round(int scale, double number) {
		double flag = 0.0F;
		String text = String.valueOf(number);
		BigDecimal bd = new BigDecimal(text).setScale(scale, BigDecimal.ROUND_HALF_UP);
		flag = bd.doubleValue();

		DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
		StringBuffer buf = new StringBuffer();
		buf.append("0");
		for (int i = 0; i < scale; i++) {
			if (buf.indexOf(".") < 0) {
				buf.append(".0");
			} else {
				buf.append("0");
			}
		}

		df.applyPattern(buf.toString());
		return df.format(flag);
	}

	/**
	 * @name toMap
	 *
	 * @param list
	 * @param keyName
	 * @return    
	 * Map     
	 * @throws 
	*/
	@SuppressWarnings("unchecked")
	public static Map toMap(List list, String keyName) {
		if (null == keyName) {
			throw new IllegalArgumentException("key can not be null");
		}
		if (null == list) {
			return null;
		}
		Map map = new HashMap();
		Object keyValue = null;
		for (Object obj : list) {
			try {
				keyValue = ReflectUtils.getFieldValue(obj, keyName, true);
				map.put(keyValue, obj);
			} catch (Exception e) {
				//throw new IllegalArgumentException(e.getMessage());
				logger.error(e.getMessage());
			}
		}
		return map;
	}

	/**
	 * @name escapeSql
	 *
	 * @param str
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String escapeSql(String str) {
		if (null == str) {
			return null;
		}
		return str.replace("[", "[[]").replace("]", "]").replace("%", "[%]").replace("_", "[_]");
	}
	
	/**
	 * @name escapeSqlAndSingleQuote
	 *
	 * @param str
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String escapeSqlAndSingleQuote(String str) {
		if (null == str) {
			return null;
		}
		return str.replace("[", "[[]").replace("]", "]").replace("%", "[%]").replace("_", "[_]").replaceAll("'", "''");
	}
	
	/**
	 * @name formatNumber
	 *
	 * @param effort
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String formatNumber(Double effort) {
		if (effort == null){
			return "0";
		}	
		BigDecimal ds = new BigDecimal(effort);
		String seffort = ds.setScale(1, BigDecimal.ROUND_HALF_UP).toString();
		if (seffort.endsWith(".0")) {
			return seffort.substring(0, seffort.indexOf('.'));
		}
		return seffort;
	}
	
	/**
	 * @name formatNumber
	 *
	 * @param scale
	 * @param effort
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String formatNumber(int scale, Double effort) {
		if (effort == null){
			return "0";
		}	
		String seffort = FormatUtils.round(scale, effort);
		if (seffort.endsWith(".00")||seffort.endsWith(".0")) {
			return seffort.substring(0, seffort.indexOf('.'));
		}else if(seffort.indexOf('.')>=0&&seffort.endsWith("0")){
			return seffort.substring(0, seffort.length()-1);
		}
		return seffort;
	}
	
	/**
	 * @name htmlEscape
	 *
	 * @param str
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String htmlEscape(String str) {
		if (str == null || str.trim().length() == 0) {
			return null;
		}
		return str.replaceAll("&", "&amp;").replaceAll("\"", "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
	}
	
	/**
	 * @name doPreciseDivide
	 *
	 * @param divisor
	 * @param dividend
	 * @param scale
	 * @param times
	 * @return    
	 * String     
	 * @throws 
	*/
	public static String doPreciseDivide(Long divisor,Long dividend,int scale,int times){
		if(dividend==0){
			return "0";
		}
	 	BigDecimal bb=new BigDecimal(divisor*times);
        BigDecimal cc=new BigDecimal(dividend);
        bb=bb.divide(cc,scale,RoundingMode.HALF_UP); 
        return bb.toPlainString();
	}
}
